namespace Hack.Decompiling.PEA.PE
{
  using System;
  using System.IO;
  using System.Collections.Generic;
  using System.Text;

  public enum DirectoryEntries : uint
  {
    Export            = 0,   // Export Directory                      (Supported)
    Import            = 1,   // Import Directory                      (Supported)
    Resource          = 2,   // Resource Directory
    Exception         = 3,   // Exception Directory
    Security          = 4,   // Security Directory                    (The RVA is filepointer)
    Relocation        = 5,   // Base Relocation Table                 (Supported)
    Debug             = 6,   // Debug Directory
    Architecture      = 7,   // Architecture Specific Data
    GlobalPointer     = 8,   // RVA of GP                             (Supported)
    TLS               = 9,   // TLS Directory
    LoadConfig        = 10,  // Load Configuration Directory
    BoundImport       = 11,  // Bound Import Directory in headers
    IAT               = 12,  // Import Address Table                  (Supported)
    DelayImport       = 13,  // Delay Load Import Descriptors
    CLR               = 14,  // COM/CLR Runtime descriptor
    Reserved          = 15,  // Emit and never use.
  }

  public unsafe struct ImageDataDirectory
  {
    #region Statics
    public static implicit operator UInt64(ImageDataDirectory entry)
    {
      return ((UInt64)entry.VirtualSize) << 32 | ((UInt64)entry.VirtualAddress);
    }
    public static ImageDataDirectory it()
    {
      return new ImageDataDirectory();
    }
    public static ImageDataDirectory of(UInt64 entry)
    {
      return new ImageDataDirectory(entry);
    }
    public static ImageDataDirectory of(UInt32 VirtualAddress, UInt32 VirtualSize)
    {
      return new ImageDataDirectory(VirtualAddress, VirtualSize);
    }
    #endregion
    #region Fields
    public UInt32 VirtualAddress;
    public UInt32 VirtualSize;
    #endregion
    #region Properties
    public UInt16 Size
    {
      get
      {
        return (UInt16)this.VirtualSize;
      }
      set
      {
        this.VirtualSize &= 0xFFFF0000;
        this.VirtualSize |= value;
      }
    }
    public UInt16 Type
    {
      get
      {
        return (UInt16)(this.VirtualSize>>16);
      }
      set
      {
        this.VirtualSize &= 0x0000FFFF;
        this.VirtualSize |= ((UInt32) value)<<16;
      }
    }
    #endregion
    #region Constructors
    public ImageDataDirectory(UInt64 entry):this((UInt32)entry,(UInt32)(entry>>32))
    {
    }
    public ImageDataDirectory(UInt32 VirtualAddress, UInt32 VirtualSize)
    {
      this.VirtualAddress = VirtualAddress;
      this.VirtualSize = VirtualSize;
    }
    #endregion
    #region Methods
    #endregion
  }
}
